home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / advanced97 / WARP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  6.7 KB  |  324 lines

  1. #include "stdlib.h"
  2. #include "stdio.h"
  3. #include "math.h"
  4. #include <GL/glut.h>
  5. #include "texture.h"
  6.  
  7. static unsigned *image;
  8. static int width, height, components;
  9. static float incr = .01, dir = 1.0;
  10. static float scale = 1.0, tscale = 1.0, trotx, troty;
  11.  
  12. static float transx = 1.0, transy, rotx, roty;
  13. static int ox = -1, oy = -1;
  14. static int mot = 0;
  15. float *wrotx = &rotx, *wroty = &roty, *wscale = &scale;
  16. #define PAN    1
  17. #define ROT    2
  18.  
  19. void
  20. pan(const int x, const int y) {
  21.     transx +=  (x-ox)/5.;
  22.     transy -= (y-oy)/5.;
  23.     ox = x; oy = y;
  24.     glutPostRedisplay();
  25. }
  26.  
  27. void
  28. rotate(const int x, const int y) {
  29.     *wrotx += x-ox;
  30.     if (*wrotx > 360.) *wrotx -= 360.;
  31.     else if (*wrotx < -360.) *wrotx += 360.;
  32.     *wroty += y-oy;
  33.     if (*wroty > 360.) *wroty -= 360.;
  34.     else if (*wroty < -360.) *wroty += 360.;
  35.     ox = x; oy = y;
  36.     glutPostRedisplay();
  37. }
  38.  
  39. void
  40. motion(int x, int y) {
  41.     if (mot == PAN) pan(x, y);
  42.     else if (mot == ROT) rotate(x,y);
  43. }
  44.  
  45. void
  46. mouse(int button, int state, int x, int y) {
  47.     if(state == GLUT_DOWN) {
  48.     switch(button) {
  49.     case GLUT_LEFT_BUTTON:
  50.         mot = PAN;
  51.         motion(ox = x, oy = y);
  52.         break;
  53.     case GLUT_MIDDLE_BUTTON:
  54.         mot = ROT;
  55.         motion(ox = x, oy = y);
  56.         break;
  57.     case GLUT_RIGHT_BUTTON:
  58.         break;
  59.     }
  60.     } else if (state == GLUT_UP) {
  61.     mot = 0;
  62.     }
  63. }
  64.  
  65. #define MAXMESH 64
  66.  
  67. float Ml[4*2*(MAXMESH+1)*2 * (MAXMESH+1)];
  68.  
  69. float N = 1.5;
  70. float B = -1.5;
  71.  
  72. void
  73. mesh1(float x0, float x1, float y0, float y1,
  74.           float s0, float s1, float t0, float t1, float z, int nx, int ny)
  75. {
  76.     float y,x,s,t,dx,dy,ds,dt,vb[3],tb[2];
  77.     float v;
  78.     float *mp = Ml;
  79.     
  80.     dx = (x1-x0)/nx;
  81.     dy = (y1-y0)/ny;
  82.     ds = (s1-s0)/nx;
  83.     dt = (t1-t0)/ny;
  84.     y = y0;
  85.     t = t0;
  86.     vb[2] = z;
  87.     while (y < y1) {
  88.         x = x0;
  89.         s = s0;
  90.         while(x <= x1) {
  91.             tb[0] = s; tb[1] = t;
  92.             vb[0] = x; vb[1] = y;
  93.             v = N*N - x*x - y*y;
  94.             if (v < 0.0) v = 0.0;
  95.             vb[2] = sqrt(v) + B;
  96.             if (vb[2] < 0.) vb[2] = 0.0;
  97.             *mp++ = tb[0];    
  98.             *mp++ = tb[1];    
  99.             mp += 2;
  100.             *mp++ = vb[0];    
  101.             *mp++ = vb[1];    
  102.             *mp++ = vb[2];    
  103.             mp++;
  104.             tb[1] = t+dt;
  105.             vb[1] = y+dy;
  106.             v = N*N - x*x - (y+dy)*(y+dy);
  107.             if (v < 0.0) v = 0.0;
  108.             vb[2] = sqrt(v) + B;
  109.             if (vb[2] < 0.) vb[2] = 0.0;
  110.             *mp++ = tb[0];    
  111.             *mp++ = tb[1];    
  112.             mp += 2;
  113.             *mp++ = vb[0];    
  114.             *mp++ = vb[1];    
  115.             *mp++ = vb[2];    
  116.             mp++;
  117.             x += dx;
  118.             s += ds;
  119.         }    
  120.         y += dy;
  121.         t += dt;
  122.     }
  123. }
  124.  
  125. void
  126. drawmesh(int nx,int ny) {
  127.     float *mp = Ml;
  128.     int i,j;
  129.  
  130.     glColor4f(1,1,1,1);
  131.     for (i = ny+1; i; i--) {
  132.         glBegin(GL_TRIANGLE_STRIP);
  133.         for (j = nx+1; j; j--) {
  134.             glTexCoord2fv(mp);
  135.             glVertex3fv(mp+4);
  136.             glTexCoord2fv(mp+8);
  137.             glVertex3fv(mp+12);    mp += 16;
  138.         }
  139.         glEnd();
  140.     }
  141. }
  142.  
  143. void
  144. move(void) {
  145.     if (N > 2.1 || N < 1.5)
  146.     dir = -dir;
  147.     N += incr*dir;
  148.     mesh1(-1.5,1.5,-1.5,1.5,0.0,1.0,0.0,1.0,0.0,64,64);
  149.     glutPostRedisplay();
  150. }
  151.  
  152. void
  153. alphaup(void) {
  154.     incr += .01;
  155.     if (incr > .1) incr = .1;
  156.     glutPostRedisplay();
  157. }
  158.  
  159. void
  160. alphadown(void) {
  161.     incr -= .01;
  162.     if (incr < 0) incr = 0;
  163.     glutPostRedisplay();
  164. }
  165.  
  166. void
  167. left(void) {
  168.     *wscale -= .1;
  169. }
  170.  
  171. void
  172. right(void) {
  173.     *wscale += .1;
  174. }
  175.  
  176. void
  177. wire(void) {
  178.     static int wire_mode;
  179.     if (wire_mode ^= 1)
  180.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  181.     else
  182.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  183. }
  184.  
  185. void
  186. tfunc(void) {
  187.     static state;
  188.     if (state ^= 1) {
  189.     wrotx = &trotx;
  190.     wroty = &troty;
  191.     wscale = &tscale;
  192.     } else {
  193.     wrotx = &rotx;
  194.     wroty = &roty;
  195.     wscale = &scale;
  196.     }
  197.  
  198. }
  199.  
  200.  
  201. void
  202. help(void) {
  203.     printf("'h'   - help\n");
  204.     printf("'w'   - wire frame\n");
  205.     printf("UP      - faster\n");
  206.     printf("DOWN  - slower\n");
  207. }
  208.  
  209. void
  210. init(char *filename) {
  211.     if (filename) {
  212.     image = read_texture(filename, &width, &height, &components);
  213.     if (image == NULL) {
  214.         fprintf(stderr, "Error: Can't load image file \"%s\".\n",
  215.             filename);
  216.         exit(EXIT_FAILURE);
  217.     } else {
  218.         printf("%d x %d image loaded\n", width, height);
  219.     }
  220.     if (components < 3 || components > 4) {
  221.         printf("must be RGB or RGBA image\n");
  222.         exit(EXIT_FAILURE);
  223.     }
  224.     } else {
  225.     int i, j;
  226.     components = 4; width = height = 128;
  227.     image = (unsigned *) malloc(width*height*sizeof(unsigned));
  228.     for (j = 0; j < height; j++)
  229.         for (i = 0; i < width; i++) {
  230.         if (i & 16)
  231.             image[i+j*width] = 0xff;
  232.         else
  233.             image[i+j*width] = 0xff00;
  234.         if (j&16)
  235.             image[i+j*width] |= 0xff0000;
  236.         }
  237.  
  238.     }
  239.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  240.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  241.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  242.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  243.     glTexImage2D(GL_TEXTURE_2D, 0, components, width,
  244.                  height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
  245.                  image);
  246.     glEnable(GL_TEXTURE_2D);
  247.     glMatrixMode(GL_TEXTURE);
  248.     glLoadIdentity();
  249.     glMatrixMode(GL_PROJECTION);
  250.     glLoadIdentity();
  251.     gluPerspective(90.,1.,.1,10.);
  252.     glMatrixMode(GL_MODELVIEW);
  253.     glLoadIdentity();
  254.     glTranslatef(0.,0.,-1.5);
  255.     glClearColor(.25, .25, .25, 0.);
  256.  
  257. }
  258.  
  259. void
  260. display(void) {
  261.     glClear(GL_COLOR_BUFFER_BIT);
  262.     glMatrixMode(GL_TEXTURE);
  263.     glPushMatrix();
  264.     glTranslatef(.5f, .5f, .5f);
  265.     glRotatef(trotx, 0.f, 0.f, 1.f);
  266.     glScalef(tscale, tscale, tscale);
  267.     glTranslatef(-.5f, -.5f, -.5f);
  268.     glMatrixMode(GL_MODELVIEW);
  269.     glPushMatrix();
  270.     glRotatef(rotx, 0.f, 0.f, 1.f);
  271.     glScalef(scale, scale, scale);
  272.     drawmesh(64,64);
  273.     glPopMatrix();
  274.     glMatrixMode(GL_TEXTURE);
  275.     glPopMatrix();
  276.     glMatrixMode(GL_MODELVIEW);
  277.     glutSwapBuffers();
  278. }
  279.  
  280. void
  281. reshape(int w, int h) {
  282.     glViewport(0, 0, w, h);
  283. }
  284.  
  285. /*ARGSUSED1*/
  286. void
  287. key(unsigned char key, int x, int y) {
  288.     switch(key) {
  289.     case '\033':    exit(0); break;
  290.     case 'h':        help(); break;
  291.     case 't':        tfunc(); break;
  292.     case 'w':        wire(); break;
  293.     }
  294. }
  295.  
  296. /*ARGSUSED1*/
  297. void
  298. special(int key, int x, int y) {
  299.     switch(key) {
  300.     case GLUT_KEY_UP:    alphaup(); break;
  301.     case GLUT_KEY_DOWN:    alphadown(); break;
  302.     case GLUT_KEY_LEFT:    left(); break;
  303.     case GLUT_KEY_RIGHT:right(); break;
  304.     }
  305. }
  306.  
  307. int
  308. main(int argc, char** argv) {
  309.     glutInitWindowSize(256, 256);
  310.     glutInit(&argc, argv);
  311.     glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);
  312.     (void)glutCreateWindow("warp");
  313.     init(argv[1]);
  314.     glutKeyboardFunc(key);
  315.     glutSpecialFunc(special);
  316.     glutDisplayFunc(display);
  317.     glutReshapeFunc(reshape);
  318.     glutIdleFunc(move);
  319.     glutMouseFunc(mouse);
  320.     glutMotionFunc(motion);
  321.     glutMainLoop();
  322.     return 0;
  323. }
  324.